package hardware;

public class Memory {
	public static int[] mem;
	public static Instruction[] instMem;
	private static int accessTime;
	public static int memorySize;
	public static int programSize;

	public Memory(int size, int access) {
		memorySize = size;
		mem = new int[memorySize - programSize];
		instMem = new Instruction[programSize];
		accessTime = access;
	}

	/**
	 * loads value from memory with a certain address.
	 * 
	 * @param address
	 *            address that i want to load from the memory.
	 * @return the value inside the memory.
	 */
	public static int load(int address) {
		return mem[address];
	}

	/**
	 * stores the value in a certain address.
	 * @param address
	 *              address that i want to store in.
	 * @param value
	 *            value i want to store.
	 */
	public static void store(int address, int value) {
		mem[address] = value;
	}

	public static int getAccessTime() {
		return accessTime;
	}

	/**
	 * loads instruction from memory with a certain PC.
	 * @param PC
	 *          PC that i want to get from it instruction.
	 * @return
	 *        instruction inside the memory.
	 */
	public static Instruction loadInstructionUsingPC(int PC) {
		return instMem[PC];
	}

	/**
	 * store the instruction with PC in the memory.
	 * @param PC
	 *          PC that i want to store in it instruction.
	 * @param instruction
	 *          instruction i want tpo store.
	 */
	public static void storeInstructionUsingPC(int PC, Instruction instruction) {
		instMem[PC] = instruction;
	}

	/**
	 * loads instruction from memory with a certain address.
	 * @param address
	 *               address that i want to load from the memory
	 * @return instruction that i want to get from the memory.
	 */
	public static Instruction loadInstructionUsingAbsoluteAddress(int address) {
		if (address - memorySize >= programSize) {
			return null;
		}
		return instMem[address - memorySize];
	}

	public String toString() {
		int temp = memorySize - programSize;
		String s = "";
		for (int i = 0; i < mem.length; i++) {
			s += "Mem[" + i + "] :" + mem[i] + "   ";
			if (i % 10 == 0)
				s += "\n";
		}

		for (int j = 0; j < instMem.length; j++) {
			s += "\n" + "Mem[" + (j + temp) + "] :"
					+ instMem[j].shortToString() + "   ";
		}
		return s;

	}

}
